package com.csdware.devilsalarm;

import static com.csdware.devilsalarm.Func_StaticMisc.copyFile;

import android.Manifest;
import android.app.AlertDialog;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.amap.api.location.AMapLocationListener;

import java.io.File;
import java.io.IOException;

public class Activity_AlarmUproar extends AppCompatActivity implements LocationListener {
    private Application_Data applicationData;
    private int PreferredLocationManagerIndex = 0;
    private long RefreshTotalSecondLeftTimestamp;

    private float TotalSecondLeft;

    private TextView DisplayLoseFileHint;
    private TextView DisplayRetrieveCountDownMinute;
    private TextView DisplayRetrieveCountDownSecond;
    private TextView DisplayCurrentCoordinate;
    private TextView DisplayTargetCoordinate;
    private TextView DisplayDistanceLeft;
    private TextView ButtonMuteAlarm;
    private Boolean isFilesRescued = false;

    private final Handler PeriodicUpdateTimeLeftHandler = new Handler();
    private Runnable PeriodicUpdateTimeLeftFunction;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        SharedPreferences SharedPrefs = getSharedPreferences("data", MODE_PRIVATE);
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        if (android.os.Build.VERSION.SDK_INT >= 30) {
            WindowInsetsController windowInsetsController = getWindow().getInsetsController();
            if (windowInsetsController != null) {
                windowInsetsController.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
                windowInsetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
            }
        }
        setContentView(R.layout.activity_alarm_uproar);

        applicationData = (Application_Data) getApplicationContext();
        TotalSecondLeft = applicationData.RetrieveTimeout;
        ButtonMuteAlarm = findViewById(R.id.bt_mute_alarm);
        ButtonMuteAlarm.setOnClickListener(view -> {
            if (applicationData.mediaPlayer != null) {
                applicationData.mediaPlayer.stop();
                applicationData.mediaPlayer.release();
                applicationData.mediaPlayer = null;
            }
        });
        DisplayRetrieveCountDownMinute = findViewById(R.id.dsp_retrieve_countdown_minute);
        DisplayRetrieveCountDownSecond = findViewById(R.id.dsp_retrieve_countdown_second);
        DisplayCurrentCoordinate = findViewById(R.id.dsp_current_coordinate);
        DisplayTargetCoordinate = findViewById(R.id.dsp_target_coordinate);
        DisplayDistanceLeft = findViewById(R.id.dsp_dist_left);
        DisplayTargetCoordinate.setText(String.format("(%.5f°,%.5f°)", applicationData.TargetLongitude, applicationData.TargetLatitude));
        DisplayLoseFileHint = findViewById(R.id.dsp_lose_file_hint);

        PreferredLocationManagerIndex = SharedPrefs.getInt("LocationChoice", 0);
        switch (PreferredLocationManagerIndex) {
            case 0:
                try {
                    AMapLocationListener AmapLocationListener = amapLocation -> {
                        if (amapLocation != null) {
                            if (amapLocation.getErrorCode() == 0) {
                                double latitude = amapLocation.getLatitude();
                                double longitude = amapLocation.getLongitude();
                                DisplayCurrentCoordinate.setText(String.format("(%.5f°,%.5f°)", longitude, latitude));
                                double Distance = Func_DistanceConvert.GetDistance(longitude, latitude, applicationData.TargetLongitude, applicationData.TargetLatitude);
                                DisplayDistanceLeft.setText(Math.round(Distance * 10.0) / 10.0 + "m");
                                if (Distance < applicationData.SafeZoneRadius) DecryptFiles();
                            } else {
                                Log.e("AmapError", "location Error, ErrCode:" + amapLocation.getErrorCode() + ", errInfo:" + amapLocation.getErrorInfo());
                            }
                        }
                    };
                    applicationData.AmapLocationManager.setLocationListener(AmapLocationListener);
                    applicationData.AmapLocationManager.startLocation();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                break;
            case 1:
                if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                        applicationData.AndroidDefaultLocationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER, 0, 0, Activity_AlarmUproar.this);
                    } else {
                        applicationData.AndroidDefaultLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, Activity_AlarmUproar.this);
                    }
                }
                break;
        }
        if (applicationData.PerformTest) {
            DisplayLoseFileHint.setText(R.string.hint_safe_mode);
            DisplayLoseFileHint.setTextColor(Color.argb(255, 71, 230, 76));
        } else {
            DisplayLoseFileHint.setText(String.format(getString(R.string.otherwise_you_will_lose), applicationData.EncryptedFileAmount));
        }

        PeriodicUpdateTimeLeftFunction = new Runnable() {
            @Override
            public void run() {
                RefreshTimeLeft();
                PeriodicUpdateTimeLeftHandler.postDelayed(this, 100);
            }
        };
        RefreshTotalSecondLeftTimestamp = System.currentTimeMillis();
//        Button bt_test = findViewById(R.id.bt_test);
//        bt_test.setOnClickListener(view -> DecryptFiles());
    }

    private void RefreshTimeLeft() {
        float RealTotalSecondLeft = TotalSecondLeft - (float) (System.currentTimeMillis() - RefreshTotalSecondLeftTimestamp) / 1000.0f;
        if (RealTotalSecondLeft < 0) {
            finishAffinity();
            System.exit(0);
        }
        int DisplayedMinuteLeft = ((int) RealTotalSecondLeft % 3600) / 60;
        int DisplayedSecondLeft = ((int) RealTotalSecondLeft % 3600) % 60;
        if (DisplayedMinuteLeft < 0) DisplayedMinuteLeft = 0;
        if (DisplayedSecondLeft < 0) DisplayedSecondLeft = 0;
        String DisplayedMinuteLeftStr;
        String DisplayedSecondLeftStr;
        if (DisplayedMinuteLeft < 10) DisplayedMinuteLeftStr = "0" + DisplayedMinuteLeft;
        else DisplayedMinuteLeftStr = String.valueOf(DisplayedMinuteLeft);
        if (DisplayedSecondLeft < 10) DisplayedSecondLeftStr = "0" + DisplayedSecondLeft;
        else DisplayedSecondLeftStr = String.valueOf(DisplayedSecondLeft);
        DisplayRetrieveCountDownMinute.setText(DisplayedMinuteLeftStr);
        DisplayRetrieveCountDownSecond.setText(DisplayedSecondLeftStr);
    }

    private void DecryptFiles() {
        if (!isFilesRescued) {
            // 加密文件
            File sourceDirectory = new File(getFilesDir(), "ENCRYPTED_FILES");
            File destinationDirectory = new File(applicationData.HijackDirectory);
            File[] files = sourceDirectory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        if (file.getName().startsWith("###")) continue;
                        try {
                            copyFile(file, new File(destinationDirectory, file.getName()));
                            file.delete();
                        } catch (IOException e) {
                            Log.e("Receiver_AlarmTimeUp", "Failed to copy file: " + file.getName(), e);
                        }
                    }
                }
            }
            // 弹出成功弹窗
            AlertDialog.Builder builder = new AlertDialog.Builder(Activity_AlarmUproar.this);
            TextView textView = new TextView(Activity_AlarmUproar.this);
            textView.setText(R.string.congrats);
            textView.setPadding(16, 16, 16, 16); // 设置内边距
            textView.setTextSize(13); // 设置字体大小
            textView.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            textView.setMovementMethod(new ScrollingMovementMethod()); // 允许滚动
            builder.setView(textView);
            AlertDialog dialog = builder.create();
            dialog.show();
        }
        isFilesRescued = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        PeriodicUpdateTimeLeftHandler.removeCallbacks(PeriodicUpdateTimeLeftFunction);  // 如果因为某些bug在任务队列里添加了多个并行的延时任务，removeCallbacks也能将它们一次全部清除
        switch (PreferredLocationManagerIndex) {
            case 0:
                applicationData.AmapLocationManager.stopLocation();
            case 1:
                applicationData.AndroidDefaultLocationManager.removeUpdates(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        PeriodicUpdateTimeLeftHandler.postDelayed(PeriodicUpdateTimeLeftFunction, 0);
        switch (PreferredLocationManagerIndex) {
            case 0:
                applicationData.AmapLocationManager.startLocation();
                break;
            case 1:
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                        applicationData.AndroidDefaultLocationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER, 0, 0, Activity_AlarmUproar.this);
                    } else {
                        applicationData.AndroidDefaultLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, Activity_AlarmUproar.this);
                    }
                }
                break;
        }
    }

    @Override
    public void onBackPressed() {
        if (isFilesRescued) {
            finishAffinity();
            System.exit(0);
        } else {
            AlertDialog dialog;
            AlertDialog.Builder builder = new AlertDialog.Builder(Activity_AlarmUproar.this)
                    .setTitle(getString(R.string.are_you_sure_to_exit))
                    .setMessage(getString(R.string.exit_no_no))
                    .setPositiveButton(getString(R.string.yes), (dialog1, which) -> {
                        dialog1.dismiss();
                        finishAffinity();
                        System.exit(0);
                    })
                    .setNegativeButton(getString(R.string.cancel), (dialog1, which) -> dialog1.dismiss());
            dialog = builder.create();
            dialog.show();
        }
    }

    @Override
    public void onLocationChanged(@NonNull Location location) {
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        DisplayCurrentCoordinate.setText(String.format("(%.5f°,%.5f°)", longitude, latitude));
        double Distance = Func_DistanceConvert.GetDistance(longitude, latitude, applicationData.TargetLongitude, applicationData.TargetLatitude);
        DisplayDistanceLeft.setText(Math.round(Distance * 1.0) / 1.0 + "m");
        if (Distance < applicationData.SafeZoneRadius) DecryptFiles();
    }
}
